<template>
	<view class="wc-lottery">
		<view class="wc-lottery__heaer"></view>
		<view class="wc-lottery__body">
			<view  
				v-for="(item, index) in localList" 
				:key="item[idField]"
				:class="[
					'wc-lottery-item flex-col-center', 
					item.status
				]"
				@click="setFlipStatus(item, index)"
			>
				
				<view v-if="item.status !== 'finished' && item.status !== 'reading'" class="wc-lottery-item__content"></view>
				<view  v-else class="wc-lottery-item__content" >
					<view class="max-money"> 
						<text class="max-money-label label">可抢最高</text>
						<text class="max-money-value value">{{ item[maxMoneyField] || maxMoney }}</text>
						<text class="max-money-unit unit"> 元 </text>
					</view>
					<view class="money">
						<text 
							class="money-value value" 
							:class="{ 'empty-value': isNotMoneyValue(item)}">
							{{ getItemText(item) }}
						</text>
						<text v-if="!isNotMoneyValue(item)" class="money-unit unit"> 元 </text>
					</view>
				</view>
			
				
				
			</view>
		</view>
		<view class="wc-lottery__footer">
			<slot name="footer"></slot>
		</view>
	</view>
</template>

<script>
	/**
	 * 上传，红包池，然后分发到单个用户单天单个视频只能领取，领取完之后失效。最大值最小值的一个设置。每个用户领的都不一样
	 * 
	 */
	/**
	 * 这个页面，应该是需要嵌入到视频页面中，通过 点击 红包按钮，弹出此页面。
	 * 这里有几个动画效果。具体步骤如下：
	 * 1. 所有奖项展示。静态
	 * 2. 所有奖项添加一个蒙层。
	 * 3. 所有奖项翻转。动画。flip 动画 
	 * 4. 所有奖项开始洗牌。集中到中间。（然后在此过程中，对数据随机排序） shuffle 动画 
	 * 5. 根据排序后的数据，再次展示到对应位置。
	 */
	
	// @todo 模拟数据，接口完成后，记得删除
	const SIMULATE_LIST = [
		{
			id: 1,
			content: '100'
		},
		{
			id: 2,
			content: '12.08'
		},
		{
			id: 3,
			content: '3.08'
		},
		{
			id: 4,
			content: '8.08'
		},
		{
			id: 5,
			content: '5.08'
		},
		{
			id: 6,
			content: ''
		}
	] 
	const delayTime = 1200
	const flipDelayTime = 2000
	export default {
		name: "Lottery",
		props: {
			
			/**
			 * 这里的数据，应该是从父组件那里传过来的，比如说，点击某个动作，会请求数据，拿到数据后再打开这个页面。
			 * 如果说需要先进入到这个页面，再来做这个动画。那动画效果应该是先给每个奖项加蒙层，点击之后，再展示所有的奖项。
			 * list里应该具备以下几个属性。
			 * list.id ,
			 * list.content,
			 */
			list: {
				type: Array,
				default() {
					return [
						...SIMULATE_LIST
					]
				}
			},
			idField: {
				type: String,
				default: 'id'
			},
			contentField: {
				type: String,
				default: 'content'
			},
			maxMoneyField: {
				type: String,
				default: 'max'
			},
			maxMoney: {
				type: String | Number,
				default: '288'
			},
			// 所选中的Id, 如果有。
			selectId: {
				type: String | Number,
				default: 4
			},
			pageMod: {
				type: String,
				default: 'page' // page 表示这是一个页面，model 表示是一个弹窗
			}
		},
		data() {
			return {
				
				localList: [],
				flipTimeDly: null, // 翻牌动画
				shuffleTimeDly: null, // 洗牌动画。
				dealTimeDly: null, // 发牌动画
				animationStatus: 'reading' ,// reading, flip, shuffle, deal, dealAfter, finished, 
			}
		},
		watch: {
			list() {
				// this.localList = [...v]
				this.dataHandler([...v])
			}
		},
		computed: {
			isShowEmptyView() {
				if (!this.animationStatus) {
					return false
				}
				return this.animationStatus !== 'reading' && this.animationStatus != 'finished'
			}
		},
		mounted() {
			const vm = this
			
			// this.localList = [...this.list]
			this.dataHandler([...this.list])
			this.flipHandler()
			
		},
		beforeDestroy() {
			if(this.flipTimeDly) {
				clearTimeout(this.flipTimeDly)
				this.flipTimeDly = null
			}
			if(this.shuffleTimeDly) {
				clearTimeout(this.shuffleTimeDly)
				this.shuffleTimeDly = null
			}
			if(this.dealTimeDly) {
				clearTimeout(this.dealTimeDly)
				this.dealTimeDly = null
			}
			this.localList.forEach(item => {
				if (item.timeDel) {
					clearTimeout(item.timeDel)
				}
			})
		},
		methods: {
			// 随机排序
			shuffle(arr) {
			  return arr.sort(() => Math.random() - 0.5);
			},
			
			dataHandler(data) {
				const vm = this
				const list = data.map(item => {
					return {
						...item,
						[vm.contentField]: vm.getItemText(item),
						isNotMoneyValue: vm.isNotMoneyValue(item),
						status: 'reading',
						timeDel: null,
					}
				})
				this.localList = [...list]
			},
			/**
			 * 这段代码，写的有点 low，要改改
			 */
			dataStatusHandler(statusText, t, callback) {
				const time = t || 0
				const len = this.localList.length
				const list = this.localList.map((item, index) => {
					if (!item.timeDel) {
						item.timeDel = null
					} else {
						clearTimeout(item.timeDel)
					}
					const itemIndex = index + 1
					if (!t) {
						return {
							...item,
							status: statusText
						}
					}
					item.timeDel =  setTimeout(() => {
						item.status = statusText
						if (len === itemIndex && callback && typeof callback === 'function') {
							callback()
						}
					}, time * itemIndex)
					return item
				})
				this.localList = [...list]
			},
			
			// 是不是一个 空 的值，例如： '', 0, '谢谢惠顾'
			isNotMoneyValue(item) {
				// 没有对应的字段, 但是，要排除 0的可能。
				if ( !item.hasOwnProperty(this.contentField) || item[this.contentField] === 0 ) {
					return true
				}
				// 内容是个空，或者内容是一个 谢谢惠顾
				return item[this.contentField] == '' || item[this.contentField] === '谢谢惠顾'
			},
			
			// content 文案格式 化，因为 是 uniapp 上写，所以，这里只能写在 methods里
			getItemText (item) {
				if (!item.hasOwnProperty(this.contentField)) {
					return '谢谢惠顾'
				}
				if (item[this.contentField] === '0' || !item[this.contentField]) {
					return '谢谢惠顾'
				}
				return item[this.contentField]
			},
			
			/**
			 * 翻牌动画延时函数执行
			 * 执行完毕后，需要执行 洗牌动作
			 */
			flipHandler() {
				const vm = this
				if (this.flipTimeDly) {
					clearTimeout(this.flipTimeDly)
					this.flipTimeDly = null
				}
				this.flipTimeDly = setTimeout(() => {
					vm.animationStatus = 'flip'
					vm.dataStatusHandler('flip', 0)
					vm.shuffleHandler()
				}, flipDelayTime)
			},
			/**
			 * 洗牌动作，
			 * 打乱数据顺序 ？ 貌似不需要。
			 * 执行完毕后，需要执行发牌动作。
			 */
			shuffleHandler() {
				const vm = this
				if (this.shuffleTimeDly) {
					clearTimeout(this.shuffleTimeDly)
					this.shuffleTimeDly = null
				}
				this.shuffleTimeDly = setTimeout(() => {
					vm.animationStatus = 'shuffle'
					vm.dataStatusHandler('shuffle', 0)
					vm.dealHandler()
				}, delayTime)
			},
			// 发牌动作
			dealHandler() {
				const vm = this
				if (this.dealTimeDly) {
					clearTimeout(this.dealTimeDly)
					this.dealTimeDly = null
				}
				this.dealTimeDly = setTimeout(() => {
					vm.animationStatus = 'deal'
					vm.dataStatusHandler('deal', 80, this.dealAfterHandler)
				}, delayTime)
			},
			
			dealAfterHandler() {
				const vm = this
				if (this.dealTimeDly) {
					clearTimeout(this.dealTimeDly)
					this.dealTimeDly = null
				}
				this.dealTimeDly = setTimeout(() => {
					vm.dataStatusHandler('flipback', 0)
					vm.localList = vm.shuffle(this.localList)
					vm.animationStatus = 'dealAfter'
				}, delayTime)
			},
			// 这里应该是跳转到一个中奖页面，或者打开一个中奖页面的弹窗
			setFlipStatus(item, index){
				console.log(item)
				const vm = this
				if (this.animationStatus !== 'dealAfter') {
					return
				}
				if (this.pageMod !== 'page') {
					this.$emit('select')
					return
				}
				if (!this.selectId) {
					item.status = 'finished'
					this.animationStatus = 'finished'
					this.dealTimeDly = setTimeout(() => {
						vm.dataStatusHandler('finished', 0)
					}, delayTime)
					this.$emit('select', item)
					return
				}
				// 找到必须要选中的项目。及其索引值。
				const clickItem = JSON.parse(JSON.stringify(item))
				const needActiveItem = this.localList.find(item => String(item[vm.idField]) === String(vm.selectId)); 
				let needActiveItemCopy = {}
				let needActiveItemIndex = 0
				if (needActiveItem) {
					needActiveItemCopy = JSON.parse(JSON.stringify(needActiveItem))
					needActiveItemCopy.status = 'finished'
					needActiveItemIndex = this.localList.findIndex(item => item[vm.idField] === vm.selectId); 
					this.$set(this.localList, index, needActiveItemCopy)
					this.$set(this.localList, needActiveItemIndex, clickItem)
					this.dealTimeDly = setTimeout(() => {
						vm.dataStatusHandler('finished', 0)
					}, delayTime)
					this.$emit('select', needActiveItemCopy)
					return
				}
				this.$emit('select', item)
			}
			
		}
	}
</script>

<style lang="scss" scoped>
	.flex-col-center {
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
	}
</style>

<style lang="scss" scoped>
	$lottery-item-w: 170rpx;
	$lottery-item-h: 220rpx;
	$lottery-item-padding: 20rpx;
	$lottery-translate-x-abs: 375rpx - $lottery-item-w;
	$lottery-translate-y-abs: ($lottery-item-h + $lottery-item-padding) / 2;
	
	.wc-lottery {
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
		width: 100%;
		// height, 调度，如果是在一个弹窗里面打开，这里的调试,应该从外面传进来。
		height: 100vh;
		// background: transparent;
	}
	.wc-lottery__body {
		display: flex;
		flex-direction: row;
		flex-wrap: wrap;
		justify-content: space-around;
		gap: 10px;
		padding: 20px 80rpx;
		
	}
	.wc-lottery-item-wrap {
		position: relative;
		width: $lottery-item-w;
		height: $lottery-item-h;
		transform-style: preserve-3d;
		transition: transform 0.3s;
		overflow: hidden;
	}
	.wc-lottery-item {
		// position: absolute;
		// left: 0;
		// top: 0;
		width: $lottery-item-w;
		height: $lottery-item-h;
		padding: $lottery-item-padding;
		background-image: url('@/static/img/lottery/lottery_item_bg.png');
		background-repeat: no-repeat;
		background-size: 100%;
		border-radius: 20rpx;
		transform-style: preserve-3d;
		transition: transform 500ms;
		
		
	}
	.wc-lottery-item__content {
		margin-top: 40rpx;
		text-align: center;
		.max-money {
			font-size: 14rpx;
			color: #fff;
		}
		.money {
			
			.money-value {
				font-family: HarmonyOS Sans SC;
				font-size: 39rpx;
				color: #F9BC79;
			}
			.empty-value {
				font-size: 20rpx;
			}
			.unit {
				font-size: 14rpx;
				color: #fff;
			}
			
		}
	}

	
	.reading {
		animation-name: animationReading;
		animation-duration: 1s;
		
	}

	// start 动画 这里之所以用 animation , 是因为希望动画完成后，rotateY 能够翻回来，
	.flip {
		animation-name: animationFlip;
		animation-duration: 400ms;
	}
	
	// $lottery-translate-x-abs 差不多是205px, 计算公司为： 屏幕宽度的一半是 375rpx, 盒子的宽是 170， 375 - 170 = 205
	// $lottery-translate-y-ab 是 120， 这是因为 height 设为 220 ，再加上padding: 20, 就是 240，240 / 2 = 220
	
	.shuffle {
		transition: transform 500ms;
	}
	
	// 第一个，向右，向下移动
	.shuffle:nth-child(1) {
		transform:  translate($lottery-translate-x-abs, $lottery-translate-y-abs);
	}
	// 第二个，只向下移动
	.shuffle:nth-child(2) {
		transform: translate(0, $lottery-translate-y-abs);
	}
	// 第三个，向左，向下移动，
	.shuffle:nth-child(3) {
		transform: translate(0 - $lottery-translate-x-abs, $lottery-translate-y-abs);
	}
	// 第四个，向右 向上移动，
	.shuffle:nth-child(4) {
		transform: translate($lottery-translate-x-abs, 0 - $lottery-translate-y-abs);
	}
	// 第5个，应该只需要向上移动
	.shuffle:nth-child(5) {
		transform: translate(0, 0 - $lottery-translate-y-abs);
	}
	// 第6个，应该是 向左 移动，向上 移动对应的单位，所以，他的两个值都是 负数
	.shuffle:nth-child(6) {
		transform: translate(0 - $lottery-translate-x-abs, 0 - $lottery-translate-y-abs);
	}
	.deal {
		transition: transform 200ms;
		transform:   translate(0, 0);
	}
	
	.flipback {
		transform: rotateY(180deg);
		transition: none;
	}
	
	@keyframes animationFlip {
	    0% {
			
			transform: rotateY(0deg);
		}
	   
	    100% {
			
	        transform: rotateY(180deg);
	    }
	}
	@keyframes animationReading {
		0% {
			opacity: 0;
			transform: scale(0);
		}
			   
		100% {
			opacity: 1;
		    transform:scale(1);
		}
	}
	
	
</style>
